package cn.edu.zut.sunday.base.service;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import cn.edu.zut.sunday.base.domain.BaseEntity;
import cn.edu.zut.sunday.base.test.BaseAbstractTestCase;
import java.io.Serializable;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;

@Slf4j
public abstract class GenericServiceTestCase<PK extends Serializable, T extends BaseEntity<PK>, M extends GenericService<T, PK>>
        extends BaseAbstractTestCase {
    protected T entity;
    protected List<T> list;
    protected M manager;

    private Class<T> entityClass;

    protected boolean isMultiTable = false;

    public GenericServiceTestCase(final Class<T> persistentClass) {
        this.entityClass = persistentClass;
    }

    @Before
    public void setUp() throws Exception {
        this.entity = this.entityClass.getDeclaredConstructor().newInstance();
    }

    @Test
    public void testCRUD() throws Exception {
        if (isMultiTable) {
            return;
        }
		//this.manager.deleteAll();
        long startCount = this.manager.count();
        int num = 10;
        int expect_idx = 5;
        T expected = null;
        for (int i = 1; i <= num; i++) {
            T e = this.entityClass.getDeclaredConstructor().newInstance();
            T saved = this.manager.save(e);
            assertNotNull(saved);
            if (i == expect_idx) {
                expected = saved;
            }
        }
        // test for findById
        T response = this.manager.findById(expected.getId());
        assertEquals(expected, response);
        // test for method count()
        long count = this.manager.count() - startCount;
        assertEquals(num, count);
    }

    @Test
    public void testQuery(){
        final Page<T> all = this.manager.findAll(PageRequest.of(0, 10));
        log.info("{}", all.getContent());
    }

}
